/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.gameserver.model.actor.instance;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.StringTokenizer;
import java.util.logging.Level;

import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.custom.HonorPointsManager;
import com.l2jserver.gameserver.custom.HonorRankModel;
import com.l2jserver.gameserver.custom.PcHonor;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.gameserver.skills.Stats;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;

/**
 * @author Home
 *
 */
public class L2HonorPointsManagerInstance extends L2Npc
{
	private static final HonorPointsManager HONOR_INSTANCE = HonorPointsManager.getInstance();
	
	public L2HonorPointsManagerInstance(int objectId, L2NpcTemplate template)
	{
		super(objectId, template);
	}
	
	public void onBypassFeedback(L2PcInstance player, String command)
	{
		StringTokenizer cmds = new StringTokenizer(command, " ");
		String actualCommand = cmds.nextToken();
		
		if ("NextRank".equalsIgnoreCase(actualCommand))
			showNextRank(player);
		else if ("RankUp".equalsIgnoreCase(actualCommand))
		{
			int nextRankLevel = -1;
			try
			{
				nextRankLevel = Integer.parseInt(cmds.nextToken());
			}
			catch (Exception e)
			{
				_log.log(Level.SEVERE, null, e);
				return;
			}
			if (nextRankLevel > 0)
				rankUp(player, nextRankLevel);
		}
		else if ("RiseStat".equalsIgnoreCase(actualCommand))
		{
			String statName = cmds.nextToken();
			if (HONOR_INSTANCE.isAllowed(Stats.valueOfXml(statName)))
			{
				showStatBonus(player, statName);
			}
		}
		else if ("RiseStatConfirm".equalsIgnoreCase(actualCommand))
		{
			String statName = cmds.nextToken();
			int amount = -1;
			try
			{
				amount = Integer.parseInt(cmds.nextToken());
			}
			catch (Exception e)
			{
				_log.log(Level.SEVERE, null, e);
				return;
			}
			if (HONOR_INSTANCE.isAllowed(Stats.valueOfXml(statName)) && amount > 0)
				confirmStatAdd(player, statName, amount);
		}
		else if ("".equalsIgnoreCase(actualCommand))
		{
			
		}
		else
			super.onBypassFeedback(player, command);
	}
	
	/**
	 * @param player
	 * @param statName
	 * @param amount
	 */
	private void confirmStatAdd(L2PcInstance player, String statName, int amount)
	{
		PcHonor honor = HONOR_INSTANCE.getHonor(player.getObjectId());
		if (honor.getStatPoints() >= amount)
		{
			honor.setStatPoints(honor.getStatPoints() - amount);
			honor.addStatAndSave(Stats.valueOfXml(statName), amount);
			honor.updateStatCalcs();
			NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
			msg.setHtml("<html>Atributo aumentado com sucesso!</html>");
			player.sendPacket(msg);
			player.updateAbnormalEffect();
			return;
		}
		else
		{
			String path = "data/html/ranks/NotEnough_stat.htm".toLowerCase();
			NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
			msg.setFile(path);
			msg.replace("%have%", "" + honor.getStatPoints());
			msg.replace("%mustHave%", "" + (amount - honor.getStatPoints()));
			player.sendPacket(msg);
			return;
		}
	}
	
	/**
	 * @param player
	 * @param statName
	 * @param amount
	 */
	private void showStatBonus(L2PcInstance player, String statName)
	{
		PcHonor honor = HONOR_INSTANCE.getHonor(player.getObjectId());
		int actualBonus = honor.getBonus(Stats.valueOfXml(statName));
		String path = "data/html/ranks/statUp_info.htm";
		NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
		msg.setFile(path);
		msg.replace("%statName%", statName);
		msg.replace("%actualBonus%", "" + actualBonus);
		msg.replace("%statLeft%", "" + honor.getStatPoints());
		player.sendPacket(msg);
	}
	
	/**
	 * @param player
	 */
	private void rankUp(L2PcInstance player, int nLevel)
	{
		HonorRankModel rank = HONOR_INSTANCE.getRanks().get(nLevel);
		PcHonor honor = HONOR_INSTANCE.getHonor(player.getObjectId());
		if ((honor.getRank().getRankLevel() + 1) != nLevel)
		{
			_log.warning("Player: " + player.getName() + " tried to make an exploit with the Honor Points System, ban him");
			return;
		}
		if (honor.getHonorPoints() >= rank.getRankPrice())
		{
			honor.setHonorPoints(honor.getHonorPoints() - rank.getRankPrice());
			honor.setRankAndAddPoints(rank);
			honor.updateTitleColor();
			if (rank.getRankItemId() != -1)
			{
				L2ItemInstance item = ItemTable.getInstance().createItem("rankup", rank.getRankItemId(), rank.getItemAmount(), null);
				player.addItem("rankup", item, null, true);
			}
			//HonorPointsManager.getInstance().setHonor(player.getObjectId(), honor);
			String path = "data/html/ranks/rankup_suc.htm";
			NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
			msg.setFile(path);
			msg.replace("%toRankName%", "" + honor.getRank().getRankLevel());
			msg.replace("%statEarned%", "" + rank.getSpendablePoints());
			player.sendPacket(msg);
			player.broadcastUserInfo();
			ThreadPoolManager.getInstance().scheduleGeneral(new SaveHonor(honor), (long) 1E3);
			return;
		}
		else
		{
			String path = "data/html/ranks/rankup_fail.htm";
			NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
			msg.setFile(path);
			player.sendPacket(msg);
			return;
		}
	}
	
	/**
	 * @param player
	 */
	private void showNextRank(L2PcInstance player)
	{
		PcHonor honor = HONOR_INSTANCE.getHonor(player.getObjectId());
		int nextLevel;
		if (honor == null)
		{
			_log.info("Honor equal to Null for player " + player.getName());
			return;
		}
		nextLevel = honor.getRank().getRankLevel() + 1;
		
		HonorRankModel nextRank = HONOR_INSTANCE.getRanks().get(nextLevel);
		if (nextRank == null)
		{
			//no more levels
			String noMoreLevels = "data/html/ranks/no_more.htm";
			NpcHtmlMessage noHtml = new NpcHtmlMessage(getObjectId());
			noHtml.setFile(noMoreLevels);
			player.sendPacket(noHtml);
			return;
		}
		String pNextRank = "data/html/ranks/next_rank.htm";
		NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
		html.setFile(pNextRank);
		html.replace("%rankName%", "" + honor.getRank() == null ? "Nenhum" : honor.getRank().getRankName());
		html.replace("%nextRankName%", nextRank.getRankName());
		html.replace("%rankPrice%", "" + nextRank.getRankPrice());
		html.replace("%statPoints%", "" + nextRank.getSpendablePoints());
		html.replace("%currentPoints%", "" + honor.getHonorPoints());
		html.replace("%rankLevel%", "" + nextRank.getRankLevel());
		player.sendPacket(html);
		
	}
	
	public static class SaveHonor extends Model
	{
		
		private final PcHonor _honor;
		
		public SaveHonor(PcHonor honor)
		{
			_honor = honor;
		}
		
		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run()
		{
			Connection con = null;
			try
			{
				con = L2DatabaseFactory.getInstance().getConnection();
				PreparedStatement statement = con.prepareStatement("UPDATE player_honors SET rankLevel = ?, stats_left = ?, honors_left = ? WHERE objectId = ?");
				statement.setInt(1, _honor.getRank().getRankLevel());
				statement.setInt(2, _honor.getStatPoints());
				statement.setInt(3, _honor.getHonorPoints());
				statement.setInt(4, _honor.getOwnerId());
				statement.executeUpdate();
			}
			catch (Exception e)
			{
				_log.log(Level.SEVERE, null, e);
			}
			finally
			{
				try
				{
					con.close();
				}
				catch (Exception e)
				{
				}
			}
			
		}
	}
	
	public static class InsertHonor extends Model
	{
		private final PcHonor _honor;
		
		public InsertHonor(PcHonor honor)
		{
			_honor = honor;
		}
		
		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run()
		{
			Connection con = null;
			try
			{
				con = L2DatabaseFactory.getInstance().getConnection();
				PreparedStatement statement = con.prepareStatement("INSERT INTO player_honors(objectId,rankLevel,stats_left,honors_left) VALUES (?,?,?,?)");
				statement.setInt(1, _honor.getOwnerId());
				statement.setInt(2, _honor.getRank().getRankLevel());
				statement.setInt(3, _honor.getStatPoints());
				statement.setInt(4, _honor.getHonorPoints());
				statement.executeUpdate();
			}
			catch (Exception e)
			{
				_log.log(Level.SEVERE, null, e);
			}
			finally
			{
				try
				{
					con.close();
				}
				catch (Exception e)
				{
				}
			}
		}
	}
	
	private static abstract class Model implements Runnable
	{
		
	}
}
